package com.yxw.yxnet_cd_center.gateway.config;

import cn.hutool.core.util.StrUtil;
import com.yxw.yxnet_cd_center.common.constant.CommonConstant;
import com.yxw.yxnet_cd_center.common.enums.CommonErrorEnum;
import com.yxw.yxnet_cd_center.common.exception.BaseException;
import com.yxw.yxnet_cd_center.common.result.TokenInfo;
import com.yxw.yxnet_cd_center.common.utils.BaseDateTime;
import com.yxw.yxnet_cd_center.common.utils.TokenUtil;
import com.yxw.yxnet_cd_center.gateway.common.UrlResolver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Optional;


/**
 *
 */
@Slf4j
@Component
public class AuthSignatureFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String url = exchange.getRequest().getURI().getPath();
        String method = exchange.getRequest().getMethodValue();
        String ip = Optional.ofNullable(exchange.getRequest().getRemoteAddress()).isPresent() ? exchange.getRequest().getRemoteAddress().toString() : "0.0.0.0";
        log.info("访问网关method方法:{},path路径:{},ip地址:{}", method, url, ip);
        String token = null;
        //不用携带token接口，放行，验证码获取等等
        if (UrlResolver.check(url)) {
            return chain.filter(exchange);
        }
        if (exchange.getRequest().getHeaders().get(CommonConstant.TOKEN) != null) {
            token = exchange.getRequest().getHeaders().get(CommonConstant.TOKEN).get(0);
        }
        log.info("请求token信息，参数：{}", token);
        if (StrUtil.isBlank(token)) {
            throw new BaseException(CommonErrorEnum.USER_TOKEN_NOT_LOGIN, "用户未登陆");
        }
        //解析token参数 jwt
        TokenInfo oTokenInfo = TokenUtil.getTokenInfoByToken(token);
        Optional.ofNullable(oTokenInfo).orElseThrow(() -> new BaseException(CommonErrorEnum.USER_TOKEN_INVALID_TOKEN, "无效的授权令牌"));

        //需要token，但是不校验过期的集合
        if (UrlResolver.checkTokenExpire(url)) {
            if (null != oTokenInfo.getExpiresAt()) {
                if (oTokenInfo.getExpiresAt().before(BaseDateTime.getDate())) {
                    throw new BaseException(CommonErrorEnum.USER_TOKEN_EXPIRE, "登录token过期，请重新获取token");
                }
            }
        }

        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
